package com.fumin.service;

import com.fumin.beans.CacheKeyConstants;
import com.fumin.util.JsonMapper;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import redis.clients.jedis.ShardedJedis;

import javax.annotation.Resource;

/**
* @Description:    处理redis缓存的类
 * 使用redis的时候要明确,哪些地方可以加,哪些地方不能加
 * 1.验证是否有访问url的权限的时候,这里要查询的数据和请求次数都比较多,而且查询一次就可以了,以后直接从缓冲中取(SysCoreService.java中的hasUrlAcl()方法)
 * 2.缓存用户的角色和权限(要查询的数据比较多)
 * 3.权限更改的时候,这个时候不要加缓存,要更新缓冲中的数据
 * 这里只列出一个例子:在SysCoreService.java中的getCurrentUserAclList()的方法,新增方法为:,返回值和etCurrentUserAclList()保持一致
* @Author:         xiayuxuanmin
* @CreateDate:     2019/11/22 10:01
* @Version:        1.0
*/
@Service
@Slf4j
public class SysCacheService {

   // @Resource(name = "redisPool")
    private RedisPool redisPool;

    /**
     * 加入缓存
     * @param toSavedValue 保存到值
     * @param timeoutSeconds 过期时间
     * @param prefix 缓存的key的前缀
     */
    public void saveCache(String toSavedValue, int timeoutSeconds, CacheKeyConstants prefix) {
        saveCache(toSavedValue, timeoutSeconds, prefix, null);
    }

    /**
     * 在redis缓存中加入
     * @param toSavedValue 待保存的值
     * @param timeoutSeconds 过期时间
     * @param prefix 前缀
     * @param keys 待保存的值对应的key数组
     */
    public void saveCache(String toSavedValue, int timeoutSeconds, CacheKeyConstants prefix, String... keys) {
        if (toSavedValue == null) {
            return;
        }
        ShardedJedis shardedJedis = null;
        try {
            //获取缓存key
            String cacheKey = generateCacheKey(prefix, keys);
            //获取redis实例
            shardedJedis = redisPool.instance();
            //加入缓存
            shardedJedis.setex(cacheKey, timeoutSeconds, toSavedValue);
        } catch (Exception e) {
            log.error("save cache exception, prefix:{}, keys:{}", prefix.name(), JsonMapper.obj2String(keys), e);
        } finally {
            redisPool.safeClose(shardedJedis);
        }
    }

    /**
     * 从redis中缓存中取值
     * @param prefix 前缀
     * @param keys redis缓存的key数组
     * @return
     */
    public String getFromCache(CacheKeyConstants prefix, String... keys) {
        ShardedJedis shardedJedis = null;
        String cacheKey = generateCacheKey(prefix, keys);
        try {
            shardedJedis = redisPool.instance();
            String value = shardedJedis.get(cacheKey);
            return value;
        } catch (Exception e) {
            log.error("get from cache exception, prefix:{}, keys:{}", prefix.name(), JsonMapper.obj2String(keys), e);
            return null;
        } finally {
            redisPool.safeClose(shardedJedis);
        }
    }

    /**
     * 生成redis的缓存key的方法
     * @param prefix 前缀
     * @param keys key的字符串数组
     * @return
     */
    private String generateCacheKey(CacheKeyConstants prefix, String... keys) {
        String key = prefix.name();
        if (keys != null && keys.length > 0) {
            key += "_" + Joiner.on("_").join(keys);
        }
        return key;
    }
}
